<template>
  <div ref="feedRef" class="feed-container" @scroll="onScroll">
    <div class="feed-list">
      <template v-for="(msg, idx) in chatMessageStore.messages" :key="idx">
        <div :class="['bubble', msg.from === 'user' ? 'right' : 'left']">
          <img class="avatar" :src="msg.avatarConfig.imgSrc" :width="msg.avatarConfig.width" :height="msg.avatarConfig.height" />
          <div class="bubble-body">
            <div v-if="msg.from === 'assistant' && msg.reasoning_content" class="think-toggle-btn" @click="toggleThink(msg)">
              <i class="icon-point"></i>
              <span>{{ msg.content ? ($t('chat.thinkingComplete') + $t('chat.thinkingTime', { time: getThinkingTime(msg) })) : $t('chat.thinking') }}</span>
              <i :class="msg.isThinkShrink ? 'icon-chevron-down-2' : 'icon-chevron-up-2'"></i>
            </div>
            <div class="content" v-html="renderMessage(msg)"></div>
            <div class="bubble-bottom-operations" v-if="msg.from === 'assistant' && msg.complete">
              <i class="icon-copy-new"></i>
              <i class="icon-like"></i>
              <i class="icon-dislike"></i>
            </div>
          </div>
        </div>
      </template>
    </div>
  </div>
</template>

<script setup lang="ts">
import { useChatMessageStore } from '@/store';
import type { IMessage } from '@/types';
import { nextTick, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
const chatMessageStore = useChatMessageStore();
const feedRef = ref();
const headspace = 20;
const stickToBottom = ref(true);
const { t } = useI18n();

const renderMessage = (msg: IMessage) => {
  const think = String(msg.reasoning_content || '');
  const text = String(msg.content || '');
  const thinkBlock = msg.isThinkShrink ? '' : (think ? `<div class="mc-think-block">${escapeHtml(think).replace(/\n/g, '<br/>')}</div>` : '');
  return `${thinkBlock}${escapeHtml(text).replace(/\n/g, '<br/>')}`;
};

const onScroll = () => {
  const el = feedRef.value;
  const distanceToBottom = el.scrollHeight - el.clientHeight - el.scrollTop;
  stickToBottom.value = distanceToBottom < headspace;
};

const toggleThink = (msg: IMessage) => { msg.isThinkShrink = !msg.isThinkShrink; };
const getThinkingTime = (msg: IMessage) => {
  if (msg.startTime && msg.endTime) return Math.round((msg.endTime - msg.startTime) / 1000);
  return 0;
};

const escapeHtml = (s: string) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');

watch(
  () => chatMessageStore.messageChangeCount,
  () => {
    nextTick(() => {
      if (!feedRef.value || !stickToBottom.value) return;
      feedRef.value.scrollTo({ top: feedRef.value.scrollHeight, behavior: 'smooth' });
    });
  },
);
</script>

<style scoped lang="scss">
@import "devui-theme/styles-var/devui-var.scss";

.feed-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: auto;
  width: 100%;
  padding-top: 20px;
}

.feed-list {
  width: 100%;
  margin: 0 auto;
  padding: 0 12px;
}

.bubble {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 8px;
  width: 100%;
}

.bubble.left { flex-direction: row; justify-content: flex-start; }
.bubble.right { flex-direction: row-reverse; justify-content: flex-end; }
.bubble.left .bubble-body { align-items: flex-start; }
.bubble.right .bubble-body { align-items: flex-end; margin-left: auto; }
.bubble.left .bubble-body { margin-right: auto; }

.avatar { border-radius: $devui-border-radius-full; }

.bubble-body { display: flex; flex-direction: column; gap: 6px; }

.content {
  max-width: 92%;
  padding: 10px 14px;
  border-radius: 12px;
  background-color: $devui-base-bg;
  box-shadow: 0px 1px 8px 0px rgba(25,25,25,0.06);
  color: $devui-text;
  word-break: break-word;
  transition: all 0.2s ease-in-out;
}

.bubble.left .content { background-color: $devui-base-bg; }
.bubble.right .content { background-color: $devui-primary-bg; }

.think-toggle-btn {
  display: flex;
  gap: 8px;
  align-items: center;
  border-radius: 10px;
  padding: 7px 10px 7px 0;
  width: fit-content;
  cursor: pointer;
  color: $devui-aide-text;
}
.think-toggle-btn:hover { color: $devui-text; }

.bubble-bottom-operations { display: flex; gap: 6px; }
.bubble-bottom-operations i { padding: 4px; border-radius: 4px; cursor: pointer; }
.bubble-bottom-operations i:hover { background-color: $devui-gray-10; }

@media screen and (max-width: 520px) {
  .content { max-width: 100%; }
}
</style>